#!/bin/bash

check_7() {
  logit ""
  local id="7"
  local desc="docker 集群配置"
  checkHeader="$id - $desc"
  info "$checkHeader"
  startsectionjson "$id" "$desc"
}

check_7_1() {
  local id="7.1"
  local desc="除非需要，不要在 Docker 引擎实例上启用群集模式 (自动的)"
  local remediation="如果在系统出错时启用了群模式，请停用: docker swarm leave"
  local remediationImpact="如果正在使用 Docker Enterprise 组件，则禁用 swarm 模式将影响这些组件的运行"
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:*\sinactive\s*" >/dev/null 2>&1; then
    pass -s "$check"
    logcheckresult "PASS"
    return
  fi
  warn -s "$check"
  logcheckresult "WARN"
}

check_7_2() {
  local id="7.2"
  local desc="确保在群中创建所需管理器节点的最小数量(自动的)"
  local remediation="如果配置的管理节点数量过多，则可以使用以下命令将超出部分作为节点降级: docker node demote <manager node ID to be demoted>"
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
    managernodes=$(docker node ls | grep -c "Leader")
    if [ "$managernodes" -eq 1 ]; then
      pass -s "$check"
      logcheckresult "PASS"
      return
    fi
    warn -s "$check"
    logcheckresult "WARN"
    return
  fi
  pass -s "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_3() {
  local id="7.3"
  local desc="默认情况下，docker swarm 服务将侦听主机上的所有接口，这可能不是必需的 (自动的)"
  local remediation="对此操作需要重新初始化群集，以指定--listen-addr 参数的特定接口"
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:*\sactive\s*" >/dev/null 2>&1; then
    $netbin -lnt | grep -e '\[::]:2377 ' -e ':::2377' -e '*:2377 ' -e ' 0\.0\.0\.0:2377 ' >/dev/null 2>&1
    if [ $? -eq 1 ]; then
      pass -s "$check"
      logcheckresult "PASS"
      return
    fi
    warn -s "$check"
    logcheckresult "WARN"
    return
  fi
  pass -s "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_4() {
  local id="7.4"
  local desc="加密覆盖网络上不同节点上的容器之间交换的数据(自动的)"
  local remediation="你需要创建 overlay 网络 使用 --opt encrypted 标志."
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  fail=0
  unencrypted_networks=""
  for encnet in $(docker network ls --filter driver=overlay --quiet); do
    if docker network inspect --format '{{.Name}} {{ .Options }}' "$encnet" | \
      grep -v 'encrypted:' 2>/dev/null 1>&2; then
      # If it's the first container, fail the test
      if [ $fail -eq 0 ]; then
        warn -s "$check"
        fail=1
      fi
      warn "     * Unencrypted overlay network: $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
      unencrypted_networks="$unencrypted_networks $(docker network inspect --format '{{ .Name }} ({{ .Scope }})' "$encnet")"
    fi
  done
  # We went through all the networks and found none that are unencrypted
  if [ $fail -eq 0 ]; then
    pass -s "$check"
    logcheckresult "PASS"
    return
  fi
  logcheckresult "WARN" "Unencrypted overlay networks:" "$unencrypted_networks"
}

check_7_5() {
  local id="7.5"
  local desc="使用 Docker 的内置秘密管理命令 (手动的)"
  local remediation="按照 docker 秘密管理方法，并用它来有效管理秘密."
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    if [ "$(docker secret ls -q | wc -l)" -ge 1 ]; then
      pass -c "$check"
      logcheckresult "PASS"
      return
    fi
    info -c "$check"
    logcheckresult "INFO"
    return
  fi
  pass -c "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_6() {
  local id="7.6"
  local desc="在自动锁定模式下运行 Docker 群管理器(自动的)"
  local remediation="如果正在初始化 swarm, 使用下面的命令: docker swarm init --autolock. 如果想在现有的swarm manager 节点上设置--autolock，请使用以下命令: docker swarm update --autolock."
  local remediationImpact="在自动锁定模式下的群体不会从重新启动恢复，需用户手动干预以输入解锁密钥。 在某些部署中，这可能不是很方便。."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    if ! docker swarm unlock-key 2>/dev/null | grep 'SWMKEY' 2>/dev/null 1>&2; then
      warn -s "$check"
      logcheckresult "WARN"
      return
    fi
    pass -s "$check"
    logcheckresult "PASS"
    return
  fi
  pass -s "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_7() {
  local id="7.7"
  local desc="定期轮换 swarm manager 自动锁定密钥(手动的)"
  local remediation="运行以下命令来更换 docker swarm unlock-key --rotate to rotate the keys. 此外，为了便于审计，维护密钥轮换记录并确保为密钥轮换符合规定周 期."
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    note -c "$check"
    logcheckresult "NOTE"
    return
  fi
  pass -c "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_8() {
  local id="7.8"
  local desc="定期更换 swarm 节点证书 (手动的)"
  local remediation="运行以下命令来设置所需的到期时间。例如： swarm update --cert-expiry 48h "
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    if docker info 2>/dev/null | grep "Expiry Duration: 2 days"; then
      pass -c "$check"
      logcheckresult "PASS"
      return
    fi
    info -c "$check"
    logcheckresult "INFO"
    return
  fi
  pass -c "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_9() {
  local id="7.9"
  local desc="根据需要轮换 CA 根证书 (手动的)"
  local remediation="运行以下命令来更换证书： docker swarm ca --rotate "
  local remediationImpact="None."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    info -c "$check"
    logcheckresult "INFO"
    return
  fi
  pass -c "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_10() {
  local id="7.10"
  local desc="管理平面流量与数据平面流量分离 (手动的)"
  local remediation="您应该分别使用用于管理和数据平面的专用接口来初始化 swarm。例子: docker swarm init --advertise-addr=192.168.0.1 --data-path-addr=17.1.0.3"
  local remediationImpact="这需要每个节点两个网络接口."
  local check="$id - $desc"
  starttestjson "$id" "$desc"

  if docker info 2>/dev/null | grep -e "Swarm:\s*active\s*" >/dev/null 2>&1; then
    info -c "$check"
    logcheckresult "INFO"
    return
  fi
  pass -c "$check (Swarm mode not enabled)"
  logcheckresult "PASS"
}

check_7_end() {
  endsectionjson
}
